package fr.cephb.operonj.core.db.binding;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.bind.tuple.TupleInput;
import com.sleepycat.bind.tuple.TupleOutput;

import fr.cephb.operonj.core.db.key.SequenceIndex;

public class SequenceBinding
	extends TupleBinding<byte[]>
	{
	@Override
	public byte[] entryToObject(TupleInput input)
		{
		final int finalLen= input.readInt();
		
		assert(finalLen<= SequenceIndex.SIZE);
		final int compressedlen=input.readInt();
		byte array[]=new byte[compressedlen];
		try
			{
			int nRead=input.read(array,0,array.length);
			if(nRead!=compressedlen)
				{
				throw new IOException("cannot read bytes="+compressedlen+" but "+nRead);
				}
			
			ByteArrayInputStream bin= new ByteArrayInputStream(array);
			GZIPInputStream zin= new GZIPInputStream(bin);
			int pos=0;
			byte result[]=new byte[finalLen];
			
			while((nRead= zin.read(result, pos, finalLen-pos))!=-1)
				{
				pos+=nRead;
				if(pos==finalLen) break;
				}
			zin.close();
			if(pos!=finalLen)
				{
				throw new IOException("cannot read bytes="+finalLen+"  but "+nRead+" array:length:"+result.length);
				}
			
			return result;
			}
		catch (Exception e)
			{
			throw new RuntimeException(e);
			}
		
		}
	
	@Override
	public void objectToEntry(byte[] array, TupleOutput output)
		{
		try
			{
			int finalLen=array.length;
			ByteArrayOutputStream bout= new ByteArrayOutputStream();
			GZIPOutputStream zout=new GZIPOutputStream(bout);
			zout.write(array, 0,finalLen );
			zout.finish();
			zout.flush();
			zout.close();
			array=bout.toByteArray();
			output.writeInt(finalLen);
			output.writeInt(array.length);
			output.write(array);
			output.flush();
			}
		catch (Exception e)
			{
			throw new RuntimeException(e);
			}
		}
	
	
	}
